1
2
3
4
5
6
7 package io.vavr.collection;
8
9 import io.vavr.*;
10 import io.vavr.control.Option;
11
12 import java.io.*;
13 import java.util.ArrayList;
14 import java.util.Comparator;
15 import java.util.NoSuchElementException;
16 import java.util.Objects;
17 import java.util.function.*;
18 import java.util.stream.Collector;
19
20
21
22
23
24
25
26 public final class HashSet<T> implements Set<T>, Serializable {
27
28 private static final long serialVersionUID = 1L;
29
30 private static final HashSet<?> EMPTY = new HashSet<>(HashArrayMappedTrie.empty());
31
32 private final HashArrayMappedTrie<T, T> tree;
33
34 private HashSet(HashArrayMappedTrie<T, T> tree) {
35 this.tree = tree;
36 }
37
38 @SuppressWarnings("unchecked")
39 public static <T> HashSet<T> empty() {
40 return (HashSet<T>) EMPTY;
41 }
42
43
44
45
46
47
48
49
50 public static <T> Collector<T, ArrayList<T>, HashSet<T>> collector() {
51 final Supplier<ArrayList<T>> supplier = ArrayList::new;
52 final BiConsumer<ArrayList<T>, T> accumulator = ArrayList::add;
53 final BinaryOperator<ArrayList<T>> combiner = (left, right) -> {
54 left.addAll(right);
55 return left;
56 };
57 final Function<ArrayList<T>, HashSet<T>> finisher = HashSet::ofAll;
58 return Collector.of(supplier, accumulator, combiner, finisher);
59 }
60
61
62
63
64
65
66
67
68
69
70 @SuppressWarnings("unchecked")
71 public static <T> HashSet<T> narrow(HashSet<? extends T> hashSet) {
72 return (HashSet<T>) hashSet;
73 }
74
75
76
77
78
79
80
81
82 public static <T> HashSet<T> of(T element) {
83 return HashSet.<T> empty().add(element);
84 }
85
86
87
88
89
90
91
92
93
94
95
96 @SafeVarargs
97 public static <T> HashSet<T> of(T... elements) {
98 Objects.requireNonNull(elements, "elements is null");
99 HashArrayMappedTrie<T, T> tree = HashArrayMappedTrie.empty();
100 for (T element : elements) {
101 tree = tree.put(element, element);
102 }
103 return tree.isEmpty() ? empty() : new HashSet<>(tree);
104 }
105
106
107
108
109
110
111
112
113
114
115
116 public static <T> HashSet<T> tabulate(int n, Function<? super Integer, ? extends T> f) {
117 Objects.requireNonNull(f, "f is null");
118 return Collections.tabulate(n, f, HashSet.empty(), HashSet::of);
119 }
120
121
122
123
124
125
126
127
128
129
130 public static <T> HashSet<T> fill(int n, Supplier<? extends T> s) {
131 Objects.requireNonNull(s, "s is null");
132 return Collections.fill(n, s, HashSet.empty(), HashSet::of);
133 }
134
135
136
137
138
139
140
141
142 @SuppressWarnings("unchecked")
143 public static <T> HashSet<T> ofAll(Iterable<? extends T> elements) {
144 Objects.requireNonNull(elements, "elements is null");
145 if (elements instanceof HashSet) {
146 return (HashSet<T>) elements;
147 } else {
148 final HashArrayMappedTrie<T, T> tree = addAll(HashArrayMappedTrie.empty(), elements);
149 return tree.isEmpty() ? empty() : new HashSet<>(tree);
150 }
151 }
152
153
154
155
156
157
158
159
160 public static <T> HashSet<T> ofAll(java.util.stream.Stream<? extends T> javaStream) {
161 Objects.requireNonNull(javaStream, "javaStream is null");
162 return HashSet.ofAll(Iterator.ofAll(javaStream.iterator()));
163 }
164
165
166
167
168
169
170
171
172 public static HashSet<Boolean> ofAll(boolean... elements) {
173 Objects.requireNonNull(elements, "elements is null");
174 return HashSet.ofAll(Iterator.ofAll(elements));
175 }
176
177
178
179
180
181
182
183
184 public static HashSet<Byte> ofAll(byte... elements) {
185 Objects.requireNonNull(elements, "elements is null");
186 return HashSet.ofAll(Iterator.ofAll(elements));
187 }
188
189
190
191
192
193
194
195
196 public static HashSet<Character> ofAll(char... elements) {
197 Objects.requireNonNull(elements, "elements is null");
198 return HashSet.ofAll(Iterator.ofAll(elements));
199 }
200
201
202
203
204
205
206
207
208 public static HashSet<Double> ofAll(double... elements) {
209 Objects.requireNonNull(elements, "elements is null");
210 return HashSet.ofAll(Iterator.ofAll(elements));
211 }
212
213
214
215
216
217
218
219
220 public static HashSet<Float> ofAll(float... elements) {
221 Objects.requireNonNull(elements, "elements is null");
222 return HashSet.ofAll(Iterator.ofAll(elements));
223 }
224
225
226
227
228
229
230
231
232 public static HashSet<Integer> ofAll(int... elements) {
233 Objects.requireNonNull(elements, "elements is null");
234 return HashSet.ofAll(Iterator.ofAll(elements));
235 }
236
237
238
239
240
241
242
243
244 public static HashSet<Long> ofAll(long... elements) {
245 Objects.requireNonNull(elements, "elements is null");
246 return HashSet.ofAll(Iterator.ofAll(elements));
247 }
248
249
250
251
252
253
254
255
256 public static HashSet<Short> ofAll(short... elements) {
257 Objects.requireNonNull(elements, "elements is null");
258 return HashSet.ofAll(Iterator.ofAll(elements));
259 }
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277 public static HashSet<Integer> range(int from, int toExclusive) {
278 return HashSet.ofAll(Iterator.range(from, toExclusive));
279 }
280
281 public static HashSet<Character> range(char from, char toExclusive) {
282 return HashSet.ofAll(Iterator.range(from, toExclusive));
283 }
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307 public static HashSet<Integer> rangeBy(int from, int toExclusive, int step) {
308 return HashSet.ofAll(Iterator.rangeBy(from, toExclusive, step));
309 }
310
311 public static HashSet<Character> rangeBy(char from, char toExclusive, int step) {
312 return HashSet.ofAll(Iterator.rangeBy(from, toExclusive, step));
313 }
314
315 @GwtIncompatible
316 public static HashSet<Double> rangeBy(double from, double toExclusive, double step) {
317 return HashSet.ofAll(Iterator.rangeBy(from, toExclusive, step));
318 }
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336 public static HashSet<Long> range(long from, long toExclusive) {
337 return HashSet.ofAll(Iterator.range(from, toExclusive));
338 }
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362 public static HashSet<Long> rangeBy(long from, long toExclusive, long step) {
363 return HashSet.ofAll(Iterator.rangeBy(from, toExclusive, step));
364 }
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382 public static HashSet<Integer> rangeClosed(int from, int toInclusive) {
383 return HashSet.ofAll(Iterator.rangeClosed(from, toInclusive));
384 }
385
386 public static HashSet<Character> rangeClosed(char from, char toInclusive) {
387 return HashSet.ofAll(Iterator.rangeClosed(from, toInclusive));
388 }
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412 public static HashSet<Integer> rangeClosedBy(int from, int toInclusive, int step) {
413 return HashSet.ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
414 }
415
416 public static HashSet<Character> rangeClosedBy(char from, char toInclusive, int step) {
417 return HashSet.ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
418 }
419
420 @GwtIncompatible
421 public static HashSet<Double> rangeClosedBy(double from, double toInclusive, double step) {
422 return HashSet.ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
423 }
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441 public static HashSet<Long> rangeClosed(long from, long toInclusive) {
442 return HashSet.ofAll(Iterator.rangeClosed(from, toInclusive));
443 }
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467 public static HashSet<Long> rangeClosedBy(long from, long toInclusive, long step) {
468 return HashSet.ofAll(Iterator.rangeClosedBy(from, toInclusive, step));
469 }
470
471 @Override
472 public HashSet<T> add(T element) {
473 return contains(element) ? this : new HashSet<>(tree.put(element, element));
474 }
475
476 @Override
477 public HashSet<T> addAll(Iterable<? extends T> elements) {
478 Objects.requireNonNull(elements, "elements is null");
479 if (isEmpty() && elements instanceof HashSet) {
480 @SuppressWarnings("unchecked")
481 final HashSet<T> set = (HashSet<T>) elements;
482 return set;
483 }
484 final HashArrayMappedTrie<T, T> that = addAll(tree, elements);
485 if (that.size() == tree.size()) {
486 return this;
487 } else {
488 return new HashSet<>(that);
489 }
490 }
491
492 @Override
493 public <R> HashSet<R> collect(PartialFunction<? super T, ? extends R> partialFunction) {
494 return ofAll(iterator().<R> collect(partialFunction));
495 }
496
497 @Override
498 public boolean contains(T element) {
499 return tree.get(element).isDefined();
500 }
501
502 @Override
503 public HashSet<T> diff(Set<? extends T> elements) {
504 Objects.requireNonNull(elements, "elements is null");
505 if (isEmpty() || elements.isEmpty()) {
506 return this;
507 } else {
508 return removeAll(elements);
509 }
510 }
511
512 @Override
513 public HashSet<T> distinct() {
514 return this;
515 }
516
517 @Override
518 public HashSet<T> distinctBy(Comparator<? super T> comparator) {
519 Objects.requireNonNull(comparator, "comparator is null");
520 return HashSet.ofAll(iterator().distinctBy(comparator));
521 }
522
523 @Override
524 public <U> HashSet<T> distinctBy(Function<? super T, ? extends U> keyExtractor) {
525 Objects.requireNonNull(keyExtractor, "keyExtractor is null");
526 return HashSet.ofAll(iterator().distinctBy(keyExtractor));
527 }
528
529 @Override
530 public HashSet<T> drop(int n) {
531 if (n <= 0) {
532 return this;
533 } else {
534 return HashSet.ofAll(iterator().drop(n));
535 }
536 }
537
538 @Override
539 public HashSet<T> dropRight(int n) {
540 return drop(n);
541 }
542
543 @Override
544 public HashSet<T> dropUntil(Predicate<? super T> predicate) {
545 Objects.requireNonNull(predicate, "predicate is null");
546 return dropWhile(predicate.negate());
547 }
548
549 @Override
550 public HashSet<T> dropWhile(Predicate<? super T> predicate) {
551 Objects.requireNonNull(predicate, "predicate is null");
552 final HashSet<T> dropped = HashSet.ofAll(iterator().dropWhile(predicate));
553 return dropped.length() == length() ? this : dropped;
554 }
555
556 @Override
557 public HashSet<T> filter(Predicate<? super T> predicate) {
558 Objects.requireNonNull(predicate, "predicate is null");
559 final HashSet<T> filtered = HashSet.ofAll(iterator().filter(predicate));
560
561 if (filtered.isEmpty()) {
562 return empty();
563 } else if (filtered.length() == length()) {
564 return this;
565 } else {
566 return filtered;
567 }
568 }
569
570 @Override
571 public <U> HashSet<U> flatMap(Function<? super T, ? extends Iterable<? extends U>> mapper) {
572 Objects.requireNonNull(mapper, "mapper is null");
573 if (isEmpty()) {
574 return empty();
575 } else {
576 final HashArrayMappedTrie<U, U> that = foldLeft(HashArrayMappedTrie.empty(),
577 (tree, t) -> addAll(tree, mapper.apply(t)));
578 return new HashSet<>(that);
579 }
580 }
581
582 @Override
583 public <U> U foldRight(U zero, BiFunction<? super T, ? super U, ? extends U> f) {
584 return foldLeft(zero, (u, t) -> f.apply(t, u));
585 }
586
587 @Override
588 public <C> Map<C, HashSet<T>> groupBy(Function<? super T, ? extends C> classifier) {
589 return Collections.groupBy(this, classifier, HashSet::ofAll);
590 }
591
592 @Override
593 public Iterator<HashSet<T>> grouped(int size) {
594 return sliding(size, size);
595 }
596
597 @Override
598 public boolean hasDefiniteSize() {
599 return true;
600 }
601
602 @Override
603 public T head() {
604 if (tree.isEmpty()) {
605 throw new NoSuchElementException("head of empty set");
606 }
607 return iterator().next();
608 }
609
610 @Override
611 public Option<T> headOption() {
612 return iterator().headOption();
613 }
614
615 @Override
616 public HashSet<T> init() {
617 return tail();
618 }
619
620 @Override
621 public Option<HashSet<T>> initOption() {
622 return tailOption();
623 }
624
625 @Override
626 public HashSet<T> intersect(Set<? extends T> elements) {
627 Objects.requireNonNull(elements, "elements is null");
628 if (isEmpty() || elements.isEmpty()) {
629 return empty();
630 } else {
631 final int size = size();
632 if (size <= elements.size()) {
633 return retainAll(elements);
634 } else {
635 final HashSet<T> results = HashSet.<T> ofAll(elements).retainAll(this);
636 return (size == results.size()) ? this : results;
637 }
638 }
639 }
640
641
642
643
644
645
646 @Override
647 public boolean isAsync() {
648 return false;
649 }
650
651 @Override
652 public boolean isEmpty() {
653 return tree.isEmpty();
654 }
655
656
657
658
659
660
661 @Override
662 public boolean isLazy() {
663 return false;
664 }
665
666 @Override
667 public boolean isTraversableAgain() {
668 return true;
669 }
670
671 @Override
672 public Iterator<T> iterator() {
673 return tree.keysIterator();
674 }
675
676 @Override
677 public int length() {
678 return tree.size();
679 }
680
681 @Override
682 public <U> HashSet<U> map(Function<? super T, ? extends U> mapper) {
683 Objects.requireNonNull(mapper, "mapper is null");
684 if (isEmpty()) {
685 return empty();
686 } else {
687 final HashArrayMappedTrie<U, U> that = foldLeft(HashArrayMappedTrie.empty(), (tree, t) -> {
688 final U u = mapper.apply(t);
689 return tree.put(u, u);
690 });
691 return new HashSet<>(that);
692 }
693 }
694
695 @Override
696 public String mkString(CharSequence prefix, CharSequence delimiter, CharSequence suffix) {
697 return iterator().mkString(prefix, delimiter, suffix);
698 }
699
700 @Override
701 public HashSet<T> orElse(Iterable<? extends T> other) {
702 return isEmpty() ? ofAll(other) : this;
703 }
704
705 @Override
706 public HashSet<T> orElse(Supplier<? extends Iterable<? extends T>> supplier) {
707 return isEmpty() ? ofAll(supplier.get()) : this;
708 }
709
710 @Override
711 public Tuple2<HashSet<T>, HashSet<T>> partition(Predicate<? super T> predicate) {
712 Objects.requireNonNull(predicate, "predicate is null");
713 final Tuple2<Iterator<T>, Iterator<T>> p = iterator().partition(predicate);
714 return Tuple.of(HashSet.ofAll(p._1), HashSet.ofAll(p._2));
715 }
716
717 @Override
718 public HashSet<T> peek(Consumer<? super T> action) {
719 Objects.requireNonNull(action, "action is null");
720 if (!isEmpty()) {
721 action.accept(iterator().head());
722 }
723 return this;
724 }
725
726 @Override
727 public HashSet<T> remove(T element) {
728 final HashArrayMappedTrie<T, T> newTree = tree.remove(element);
729 return (newTree == tree) ? this : new HashSet<>(newTree);
730 }
731
732 @Override
733 public HashSet<T> removeAll(Iterable<? extends T> elements) {
734 return Collections.removeAll(this, elements);
735 }
736
737 @Override
738 public HashSet<T> replace(T currentElement, T newElement) {
739 if (tree.containsKey(currentElement)) {
740 return remove(currentElement).add(newElement);
741 } else {
742 return this;
743 }
744 }
745
746 @Override
747 public HashSet<T> replaceAll(T currentElement, T newElement) {
748 return replace(currentElement, newElement);
749 }
750
751 @Override
752 public HashSet<T> retainAll(Iterable<? extends T> elements) {
753 return Collections.retainAll(this, elements);
754 }
755
756 @Override
757 public HashSet<T> scan(T zero, BiFunction<? super T, ? super T, ? extends T> operation) {
758 return scanLeft(zero, operation);
759 }
760
761 @Override
762 public <U> HashSet<U> scanLeft(U zero, BiFunction<? super U, ? super T, ? extends U> operation) {
763 return Collections.scanLeft(this, zero, operation, HashSet::ofAll);
764 }
765
766 @Override
767 public <U> HashSet<U> scanRight(U zero, BiFunction<? super T, ? super U, ? extends U> operation) {
768 return Collections.scanRight(this, zero, operation, HashSet::ofAll);
769 }
770
771 @Override
772 public Iterator<HashSet<T>> slideBy(Function<? super T, ?> classifier) {
773 return iterator().slideBy(classifier).map(HashSet::ofAll);
774 }
775
776 @Override
777 public Iterator<HashSet<T>> sliding(int size) {
778 return sliding(size, 1);
779 }
780
781 @Override
782 public Iterator<HashSet<T>> sliding(int size, int step) {
783 return iterator().sliding(size, step).map(HashSet::ofAll);
784 }
785
786 @Override
787 public Tuple2<HashSet<T>, HashSet<T>> span(Predicate<? super T> predicate) {
788 Objects.requireNonNull(predicate, "predicate is null");
789 final Tuple2<Iterator<T>, Iterator<T>> t = iterator().span(predicate);
790 return Tuple.of(HashSet.ofAll(t._1), HashSet.ofAll(t._2));
791 }
792
793 @Override
794 public HashSet<T> tail() {
795 if (tree.isEmpty()) {
796 throw new UnsupportedOperationException("tail of empty set");
797 }
798 return remove(head());
799 }
800
801 @Override
802 public Option<HashSet<T>> tailOption() {
803 if (tree.isEmpty()) {
804 return Option.none();
805 } else {
806 return Option.some(tail());
807 }
808 }
809
810 @Override
811 public HashSet<T> take(int n) {
812 if (n >= size() || isEmpty()) {
813 return this;
814 } else if (n <= 0) {
815 return empty();
816 } else {
817 return ofAll(() -> iterator().take(n));
818 }
819 }
820
821 @Override
822 public HashSet<T> takeRight(int n) {
823 return take(n);
824 }
825
826 @Override
827 public HashSet<T> takeUntil(Predicate<? super T> predicate) {
828 Objects.requireNonNull(predicate, "predicate is null");
829 return takeWhile(predicate.negate());
830 }
831
832 @Override
833 public HashSet<T> takeWhile(Predicate<? super T> predicate) {
834 Objects.requireNonNull(predicate, "predicate is null");
835 final HashSet<T> taken = HashSet.ofAll(iterator().takeWhile(predicate));
836 return taken.length() == length() ? this : taken;
837 }
838
839
840
841
842
843
844
845
846
847 public <U> U transform(Function<? super HashSet<T>, ? extends U> f) {
848 Objects.requireNonNull(f, "f is null");
849 return f.apply(this);
850 }
851
852 @Override
853 public java.util.HashSet<T> toJavaSet() {
854 return toJavaSet(java.util.HashSet::new);
855 }
856
857 @SuppressWarnings("unchecked")
858 @Override
859 public HashSet<T> union(Set<? extends T> elements) {
860 Objects.requireNonNull(elements, "elements is null");
861 if (isEmpty()) {
862 if (elements instanceof HashSet) {
863 return (HashSet<T>) elements;
864 } else {
865 return HashSet.ofAll(elements);
866 }
867 } else if (elements.isEmpty()) {
868 return this;
869 } else {
870 final HashArrayMappedTrie<T, T> that = addAll(tree, elements);
871 if (that.size() == tree.size()) {
872 return this;
873 } else {
874 return new HashSet<>(that);
875 }
876 }
877 }
878
879 @Override
880 public <T1, T2> Tuple2<HashSet<T1>, HashSet<T2>> unzip(
881 Function<? super T, Tuple2<? extends T1, ? extends T2>> unzipper) {
882 Objects.requireNonNull(unzipper, "unzipper is null");
883 final Tuple2<Iterator<T1>, Iterator<T2>> t = iterator().unzip(unzipper);
884 return Tuple.of(HashSet.ofAll(t._1), HashSet.ofAll(t._2));
885 }
886
887 @Override
888 public <T1, T2, T3> Tuple3<HashSet<T1>, HashSet<T2>, HashSet<T3>> unzip3(
889 Function<? super T, Tuple3<? extends T1, ? extends T2, ? extends T3>> unzipper) {
890 Objects.requireNonNull(unzipper, "unzipper is null");
891 final Tuple3<Iterator<T1>, Iterator<T2>, Iterator<T3>> t = iterator().unzip3(unzipper);
892 return Tuple.of(HashSet.ofAll(t._1), HashSet.ofAll(t._2), HashSet.ofAll(t._3));
893 }
894
895 @Override
896 public <U> HashSet<Tuple2<T, U>> zip(Iterable<? extends U> that) {
897 return zipWith(that, Tuple::of);
898 }
899
900 @Override
901 public <U, R> HashSet<R> zipWith(Iterable<? extends U> that, BiFunction<? super T, ? super U, ? extends R> mapper) {
902 Objects.requireNonNull(that, "that is null");
903 Objects.requireNonNull(mapper, "mapper is null");
904 return HashSet.ofAll(iterator().zipWith(that, mapper));
905 }
906
907 @Override
908 public <U> HashSet<Tuple2<T, U>> zipAll(Iterable<? extends U> that, T thisElem, U thatElem) {
909 Objects.requireNonNull(that, "that is null");
910 return HashSet.ofAll(iterator().zipAll(that, thisElem, thatElem));
911 }
912
913 @Override
914 public HashSet<Tuple2<T, Integer>> zipWithIndex() {
915 return zipWithIndex(Tuple::of);
916 }
917
918 @Override
919 public <U> HashSet<U> zipWithIndex(BiFunction<? super T, ? super Integer, ? extends U> mapper) {
920 Objects.requireNonNull(mapper, "mapper is null");
921 return HashSet.ofAll(iterator().zipWithIndex(mapper));
922 }
923
924
925
926 @Override
927 public boolean equals(Object o) {
928 return Collections.equals(this, o);
929 }
930
931 @Override
932 public int hashCode() {
933 return Collections.hashUnordered(this);
934 }
935
936 @Override
937 public String stringPrefix() {
938 return "HashSet";
939 }
940
941 @Override
942 public String toString() {
943 return mkString(stringPrefix() + "(", ", ", ")");
944 }
945
946 private static <T> HashArrayMappedTrie<T, T> addAll(HashArrayMappedTrie<T, T> initial,
947 Iterable<? extends T> additional) {
948 HashArrayMappedTrie<T, T> that = initial;
949 for (T t : additional) {
950 that = that.put(t, t);
951 }
952 return that;
953 }
954
955
956
957
958
959
960
961
962
963
964
965 @GwtIncompatible("The Java serialization protocol is explicitly not supported")
966 private Object writeReplace() {
967 return new SerializationProxy<>(this.tree);
968 }
969
970
971
972
973
974
975
976
977
978 @GwtIncompatible("The Java serialization protocol is explicitly not supported")
979 private void readObject(ObjectInputStream stream) throws InvalidObjectException {
980 throw new InvalidObjectException("Proxy required");
981 }
982
983
984
985
986
987
988
989
990
991 @GwtIncompatible("The Java serialization protocol is explicitly not supported")
992 private static final class SerializationProxy<T> implements Serializable {
993
994 private static final long serialVersionUID = 1L;
995
996
997 private transient HashArrayMappedTrie<T, T> tree;
998
999
1000
1001
1002
1003
1004
1005
1006
1007 SerializationProxy(HashArrayMappedTrie<T, T> tree) {
1008 this.tree = tree;
1009 }
1010
1011
1012
1013
1014
1015
1016
1017 private void writeObject(ObjectOutputStream s) throws IOException {
1018 s.defaultWriteObject();
1019 s.writeInt(tree.size());
1020 for (Tuple2<T, T> e : tree) {
1021 s.writeObject(e._1);
1022 }
1023 }
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033 private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException {
1034 s.defaultReadObject();
1035 final int size = s.readInt();
1036 if (size < 0) {
1037 throw new InvalidObjectException("No elements");
1038 }
1039 HashArrayMappedTrie<T, T> temp = HashArrayMappedTrie.empty();
1040 for (int i = 0; i < size; i++) {
1041 @SuppressWarnings("unchecked")
1042 final T element = (T) s.readObject();
1043 temp = temp.put(element, element);
1044 }
1045 tree = temp;
1046 }
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057 private Object readResolve() {
1058 return tree.isEmpty() ? HashSet.empty() : new HashSet<>(tree);
1059 }
1060 }
1061 }